#include "NameSvrBusiness.h"
#include "MysqlConnAutoPtr.h"
#include "SFSDBOperation.h"

#define LOGGER_NAME "shadow.sfs.namesvr.namesvrbusiness"

NameSvrBusiness::NameSvrBusiness() {
		 _logger = log4cxx::Logger::getLogger(LOGGER_NAME);
}

int NameSvrBusiness::init(const char * mysqld_host, const int mysqld_port, \
				const char * mysqld_user, const char * mysqld_passwd, const int mysql_conn_pool_num) {
		if (NULL == mysqld_host || mysqld_port < 1 || NULL == mysqld_user || NULL == mysqld_passwd || \
						mysql_conn_pool_num < 1) {
				LOG4CXX_ERROR(_logger, "NameSvrBusiness init error, invalid args");
				return -1;
		}
		int res = _mysql_conn_pool.init(mysql_conn_pool_num, mysqld_host, mysqld_port, SFS_DB_NAME, mysqld_user, \
						mysqld_passwd);
		if (res < 0) {
				LOG4CXX_ERROR(_logger, "mysql conn pool init error, res:" << res);
				return -2;
		}
		return 1;
}

NameSvrBusiness::~NameSvrBusiness() {}

int NameSvrBusiness::gen_file_name(string & file_name) {
		MysqlConnAutoPtr mysql_conn_ptr(&_mysql_conn_pool);
		MYSQL_CONN * mysql_conn = mysql_conn_ptr.acquire();
		if (NULL == mysql_conn) {
				LOG4CXX_ERROR(_logger, "can not get mysql conn in gen_file_name");
				return -1;
		}
		list<SFS_NAMESPACE_CONFIG> l_namespace_config;
		SFSDBOperation sfs_dbop;
		int res = sfs_dbop.get_all_namespace_config(mysql_conn->mysql, l_namespace_config);
		if (res < 0) {
				LOG4CXX_ERROR(_logger, "gen_file_name error, try to get all namespace config from db error, res:" << res);
				return -2;
		}
		int weight_total(0);
		list<SFS_NAMESPACE_CONFIG> l_t;
		for (list<SFS_NAMESPACE_CONFIG>::const_iterator iter = l_namespace_config.begin(); \
						l_namespace_config.end() != iter; iter++) {
				if (iter->namespace_weight > 0) {
						weight_total += iter->namespace_weight;
						l_t.push_back(*iter);
				}
		}
		if (weight_total < 1 || l_t.size() < 1) return -3;
		static unsigned int seed = time(NULL);
		int rand = rand_r(&seed);
		rand = rand % weight_total;
		int s(0);
		int namespace_id(-1);
		char tbuf[1024];
		for(list<SFS_NAMESPACE_CONFIG>::const_iterator iter = l_t.begin(); l_t.end() != iter; iter++) {
				s += iter->namespace_weight;
				if (s >= rand) {
						namespace_id = iter->namespace_id;
						break;
				}
		}
		snprintf(tbuf, sizeof(tbuf), "/%d", namespace_id);
		file_name = tbuf; 
		for (int i = 0; i < FILE_HASH_LEVEL; i++) {
				rand = rand_r(&seed);
				rand = rand % NUM_DIR_PER_HASH_LEVEL;
				snprintf(tbuf, sizeof(tbuf), "/%d", rand);
				file_name += tbuf; 
		}
		rand = rand_r(&seed);
		snprintf(tbuf, sizeof(tbuf), "/%d", rand);
		file_name += tbuf;
		LOG4CXX_INFO(_logger, "gen_file_name ok:" << file_name);
		return 1;
}
